package org.emet.service.storage;

import java.math.BigDecimal;
import java.util.List;

import org.apache.log4j.Logger;
import org.emet.dao.storage.ItemDao;
import org.emet.dao.storage.PurchaseHistDao;
import org.emet.dao.storage.PurchaseItemDao;
import org.emet.entity.storage.Item;
import org.emet.entity.storage.PurchaseHist;
import org.emet.entity.storage.PurchaseItem;
import org.emet.jee.BusinessException;
import org.emet.jee.console.entity.security.User;
import org.emet.jee.console.services.security.SpringSecurityService;
import org.emet.jee.core.dao.Page;
import org.emet.service.dto.storage.PurchaseCriteria;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.flex.remoting.RemotingDestination;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
@RemotingDestination
public class PurchaseMananger {
	private Logger logger = Logger.getLogger(PurchaseMananger.class);

	@Autowired
	private SpringSecurityService springSecurityService;
	@Autowired
	private PurchaseHistDao purchaseHistDao;
	@Autowired
	private ItemDao itemDao;
	@Autowired
	private PurchaseItemDao purchaseItemDao;

	public Page<PurchaseHist> searchPurchaseHist(Page<PurchaseHist> page, PurchaseCriteria c) {
		return purchaseHistDao.search(page, c);
	}

	private boolean hasOperator(PurchaseHist order) {
		return order.getOperatorName() != null || order.getOperatorSN() != null;
	}

	public void savePurchase(PurchaseHist entity) {
		Transaction tx = purchaseItemDao.getSession().beginTransaction();
		try {
			if (entity.getId() != null) {
				PurchaseHist hist = purchaseHistDao.get(entity.getId());
				// 减去库存数量和成本金额
				updateRepository(hist.getItems());

				List<PurchaseItem> items = hist.getItems();
				for (PurchaseItem purchaseItem : items) {
					purchaseItemDao.delete(purchaseItem);
				}
				hist.setDate(entity.getDate());
				hist.setVender(hist.getVender());

				hist.setItems(entity.getItems());
				updateItems(hist);
			} else {
				updateItems(entity);
			}
			tx.commit();
		} catch (Exception e) {
			tx.rollback();
			final String message = "保存入库信息是发生错误！";
			logger.error(message, e);
			throw new BusinessException(e);
		}
	}

	private void updateItems(PurchaseHist entity) {
		final List<PurchaseItem> items = entity.getItems();
		// 增加库存数量和成本金额,修改加权价
		for (PurchaseItem entry : items) {
			entry.setDate(entity.getDate());
			entry.setBuyHistory(entity);
			Item oldItem = itemDao.get(entry.getItem().getId());
			oldItem.setStockQuatity(oldItem.getStockQuatity() + entry.getItemCount());
			oldItem.setTotalCost(oldItem.getTotalCost().add(entry.getAmount()));

			BigDecimal weightPrice = ItemHelper.calculateWeight(oldItem.getTotalCost(), oldItem.getStockQuatity());
			oldItem.setWeightPrice(weightPrice);
		}
		if (!hasOperator(entity)) {
			User currentUser = springSecurityService.getUser();
			if (currentUser != null) {
				entity.setOperatorSN(currentUser.getStaffNumber());
				entity.setOperatorName(currentUser.getName());
			}
		}
		purchaseHistDao.save(entity);
	}

	public void deletePurchase(long id) {
		PurchaseHist history = purchaseHistDao.get(id);
		if (history == null)
			return;

		// 减去库存数量和成本金额
		List<PurchaseItem> items = history.getItems();
		updateRepository(items);

		try {
			purchaseHistDao.delete(id);
		} catch (Exception e) {
			final String message = "删除入库信息是发生错误！";
			logger.error(message, e);
			throw new BusinessException(e);
		}

	}

	private void updateRepository(List<PurchaseItem> items) {
		for (PurchaseItem entry : items) {
			Item oldItem = itemDao.get(entry.getItem().getId());
			final int stockQuatity = oldItem.getStockQuatity() - entry.getItemCount();

			if (stockQuatity < 0) {
				oldItem.setStockQuatity(0);
			}

			oldItem.setStockQuatity(stockQuatity);

			/** 检测是否已经收回成本 */
			if (oldItem.getTotalCost().compareTo(new BigDecimal(0.00)) != 0) {
				/** 成本总额 */
				BigDecimal costAmount = oldItem.getTotalCost().subtract(entry.getAmount());
				if (costAmount.compareTo(new BigDecimal(0.00)) < 0) {
					/** 已经收回成本 */
					costAmount = new BigDecimal(0.00);
				}
				oldItem.setTotalCost(costAmount);
			}

			if (oldItem.getStockQuatity() == 0) {
				oldItem.setWeightPrice(new BigDecimal(0.00));
			} else {
				BigDecimal weightPrice = ItemHelper.calculateWeight(oldItem.getTotalCost(), oldItem.getStockQuatity());
				oldItem.setWeightPrice(weightPrice);
			}
		}
	}

	public java.sql.Date getDate() {
		return new java.sql.Date(new java.util.Date().getTime());
	}

}
